﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SystemAnalizer.Models;
using SystemAnalizer.Common;


namespace SystemAnalizer.Algorithms
{
    public class Danilevski
    {
        public Danilevski(double[, ,] pMatrixDiscretes, int pRow, int pColumn, string pParam, int pTnyu, int pH, int pDiscretesQuantity)
        {
            discretesQuantity = pDiscretesQuantity;

            row = pRow;
            column = pColumn;
            tnyu                = pTnyu;
            H                   = pH;
            param               = pParam;

            for (int l = 0; l < this.discretesQuantity; l++)
                for (int i = 0; i < this.row; i++)
                    for (int j = 0; j < this.column; j++)
                    {
                        this.matrixDiscretes.setDiscrete(l, i, j, pMatrixDiscretes[l, i, j]);
                        this.matrixForEignVector.setDiscrete(l, i, j, pMatrixDiscretes[l, i, j]);
                    }
            //matrixDiscretes = pMatrixDiscretes;
            //matrixForEignVector = pMatrixDiscretes;

        }

        public void calculate()
        {
            matrixForEignVector.E();
            for(int i = row-1; i>=1; --i)
            {
                if(0 == matrixDiscretes.getDiscrete(i, i-1, 0))
                {
                    for(int l = i-2; l >= 0; --l) //this for columns
                    {
                        if(0 != matrixDiscretes.getDiscrete(i, l, 0))
                        {
                            matrixDiscretes.SwapRows(l, i-1);
                            matrixDiscretes.SwapColumns(l, i-1);
                            break;
                        }
                    }
                    //matrixDiscretes->show();
                 }
       //
                if(matrixDiscretes.getDiscrete(i, i-1, 0) != 0)//->getDiscrete(i, i-1, 0))
                {
                     MatrixOfDiscretes M = new MatrixOfDiscretes(row, column, param, tnyu, H, discretesQuantity);
                    //double[, ,] M;
                     M.E();

                     MatrixOfDiscretes Mh = new MatrixOfDiscretes(row, column, param, tnyu, H, discretesQuantity);
                   // double[, ,] Mh;
                    Mh.E();
           // Calculation of M inverse matric
                   for(int j = 0; j < column; ++j)
                    {
                      List<double> tmp = new List<double>(discretesQuantity);
                      if(j != i-1)
                      {
                        tmp = matrixDiscretes.Divide(i, j, i, i-1 );
                        for(int l = 0; l < discretesQuantity; ++l)
                        {
                           tmp[l] = -tmp[l];
                        }
                    }
                    else
                    {
                        List<double> one = M.getDiscretes(0,0); //M == E, so 0,0 is eqal to 1
                        tmp = matrixDiscretes.Divide(one, i, j);//j==i-1
                    }

                    M.setDiscrete(i-1, j, tmp);
            }
            for(int j = 0; j < column; ++j)
            {
                List<double> tmp = new List<double>(discretesQuantity);
                tmp = matrixDiscretes.getDiscretes(i, j);
                Mh.setDiscrete(i-1, j, tmp);
            }
            //Mh.show();
            matrixDiscretes = Mh.Multiply(matrixDiscretes.Multiply(M));
            //matrixDiscretes->show();
            matrixForEignVector = matrixForEignVector.Multiply(M);
       }

   }


}









        protected int row;
        protected int column;
        protected int tnyu;
        protected int H;
        protected int discretesQuantity;
        protected string param;
        protected DiscreteMaker discretes;
        protected MatrixOfDiscretes matrixDiscretes;
        protected MatrixOfDiscretes matrixForEignVector;
    }
}
